/******************************************************************************
	Cobalt - utility libraries for building XNA games
	Copyright (C) 2008 Philip Djonov

	This program is free software; you can redistribute it and/or modify it
	under the terms of the GNU General Public License as published by the Free
	Software Foundation; either version 2 of the License, or (at your option)
	any later version.

	This program is distributed in the hope that it will be useful, but
	WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
	or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
	for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the
	
		Free Software Foundation, Inc.
		51 Franklin Street, Fifth Floor
		Boston, MA  02110-1301, USA.
******************************************************************************/

using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace Cobalt.Framework.Graphics
{
	public sealed class Font
	{
		internal Font()
		{
		}

		internal Texture2D[] Sheets;

		internal struct Glyph
		{
			public Texture2D Sheet;

			public Vector2 DrawOffset, DrawSize;
			public Rectangle SourceRectangle;
			public float KernA, KernB, KernC;

			/// <summary>
			/// 0 means no other case
			/// &lt; 0 means other case is lower
			/// &gt; 0 means other case is upper
			/// actual index is abs( OtherCaseIndex ) - 1
			/// </summary>
			public int OtherCaseIndex;
		}

		internal int[] Characters;

		internal sealed class FontPoint
		{
			public float PointSize;
			public float LineHeight;
			public float BaseLine;
			public float Spacing;

			public Glyph[] Glyphs;
		}

		internal FontPoint[] Points;

		internal int DefaultGlyphIndex;

		internal int GetCharacterIndex( int ch )
		{
			return Array.BinarySearch<int>( Characters, ch );
		}

		internal FontPoint GetPoint( float pointSize )
		{
			for( int i = 1; i < Points.Length; i++ )
			{
				FontPoint pa = Points[i - 1];
				FontPoint pb = Points[i];

				if( pointSize < pa.PointSize || pointSize > pb.PointSize )
					continue;

				if( (pointSize - pa.PointSize) <= (pb.PointSize - pointSize) * 0.5F )
					return pa;
				else
					return pb;
			}

			if( pointSize < Points[0].PointSize )
				return Points[0];
			else
				return Points[Points.Length - 1];
		}
	}
}